import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { APIBase, ListOption, ListResult } from 'app/modules/base/api-base';
import {
  TaskListOption,
  TaskType,
  TaskCategory,
  TaskStatus,
  TaskTarget,
  TaskPeriod,
} from 'app/modules/task/services/task.service';
import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { FormBuilder, Validators, FormArray, FormGroup, FormControl } from '@angular/forms';

@Injectable({
  providedIn: 'root',
})
export class ClientMessageService extends APIBase<ClientMessageTask, MessageTaskInfo>
  implements Resolve<ListResult<MessageTaskInfo>> {
  constructor(private fb: FormBuilder, private http: HttpClient) {
    super(http, '/api/admin/task');
  }
  // 创建消息任务，发送平台消息
  create(mt: ClientMessageTask) {
    return super.create({ ...mt, type: TaskType.Message });
  }
  // 从任务列表中抽取消息列表
  list(opt: { [key in keyof TaskListOption]?: TaskListOption[key] }) {
    return super.list(<TaskListOption>{ ...opt, category: 'all', type: TaskType.Message });
  }
  //平台消息列表路由预加载
  async resolve(route: ActivatedRouteSnapshot) {
    const page = Number(route.queryParamMap.get('page'));
    const count = Number(route.queryParamMap.get('count')) || 10;
    const type = route.paramMap.get('type');
    const keyword = route.queryParamMap.get('keyword');

    if (type === 'all') {
      return this.list({ page, keyword, count });
    }
    const messageStatus: { [key: string]: TaskStatus[] } = {
      success: [TaskStatus.Finish, TaskStatus.Failed],
      suspend: [TaskStatus.Waiting],
      sending: [TaskStatus.Running, TaskStatus.Pause],
    };
    return this.list({ page, keyword, count, status: messageStatus[type] });
  }

  // 平台消息周期发送必选周期
  weekTimeValidator(group: FormArray) {
    if (!group.value.some(Boolean)) {
      return { required: true };
    }
    return null;
  }
  // 平台消息接受者 校验用户和区域必选
  receiverValidator(control: FormControl) {
    if (control.value.users.length || control.value.zones.length) {
      return null;
    }
    return { required: true };
  }

  // 发送平台消息表单组
  sendFormGroup() {
    const group = this.fb.group({
      title: ['', [Validators.pattern(""),Validators.required]],
      content: ['', [Validators.pattern(""),Validators.required]],
      period_type: [TaskPeriod.Now, Validators.required],
      date_time: [new Date()],
      week_time: this.fb.group({
        time: [new Date()],
        weekdays: this.fb.array(new Array(7).fill(false)),
      }),
      receiver: [{ users: [], zones: [] }, this.receiverValidator],
    });

    // 根据执行规则动态设置表单校验规则
    group.get('period_type').valueChanges.subscribe((type: TaskPeriod) => {
      const date_time = group.get('date_time');
      const week_time = group.get(['week_time', 'time']);
      const week_days = group.get(['week_time', 'weekdays']);
      const periodGroup = { date_time, week_time, week_days };
      Object.values(periodGroup).forEach(control => control.setValidators(null));
      switch (type) {
        case TaskPeriod.Schedule:
          week_time.setValidators(Validators.required);
          week_days.setValidators(this.weekTimeValidator);
          break;
        case TaskPeriod.Timing:
          date_time.setValidators(Validators.required);
          break;
      }
      Object.values(periodGroup).forEach(control => control.updateValueAndValidity());
    });
    return group;
  }
}
export interface ClientMessageTask {
  type?: TaskType;
  target: TaskTarget;
  period_type: number;
  users: { id: number }[];
  areas: { id: number }[];
  content: { title: string; message: string };
  weekdays?: boolean[];
  planned_at?: Date;
}

interface MessageTaskInfo {
  id: number;
  type: number;
  admin: Admin;
  AdminID: number;
  period_type: number;
  planned_at: string;
  status: number;
  target: number;
  areas?: any;
  users?: any;
  computers?: any;
  jobs: Job[];
  created_at: string;
  updated_at: string;
  weekdays: boolean[];
}

interface Job {
  id: number;
  TaskID: number;
  type: number;
  period_type: number;
  failed: number;
  finish: number;
  total: number;
  area_count: number;
  areas?: any;
  users?: any;
  computers?: any;
  status: number;
  planned_at: string;
  start_at: string;
  end_at?: any;
  created_at: string;
  updated_at: string;
}

interface Admin {
  ID: number;
  LevelStruct: string;
  RoleID: number;
  AreaIDs: string;
  Username: string;
  Password: string;
  CreatedAt: string;
}
